package nevo.pkgs.es;

import java.util.*;

import nevo.core.*;


public class DeltaMutator implements Mutator
{
	protected double maxdelta;
	protected double mindelta;
	
	public void setMaxdelta(double m) { maxdelta = m; }
	public double getMaxdelta() { return maxdelta; }
	
	public void setMindelta(double m) { mindelta = m; }
	public double getMindelta() { return mindelta; }
	
	public DeltaMutator()
	{
		maxdelta = 1;
		mindelta = 0;
	}
		
	public IRecord mutate(IRecord i) throws Exception
	{
		IRecord child = new IRecord();
      Map<String,Object> newvals = new HashMap<String,Object>();
		
		Map<String, Object> vals = i.getInput();
		Object oldval, newval;
		for (Map.Entry<String, Object> entry : vals.entrySet()) {
			oldval = entry.getValue();
			newval = mutateObject(oldval);
			newvals.put(entry.getKey(), newval);
		}
		child.setInput(newvals);
		
		return child;
	}
	
	protected Object mutateObject(Object val) throws Exception
	{	
		if (val instanceof Double) {
			return (getDelta() + (Double) val);
		} else if (val instanceof Integer) {			
			return (Math.round(getDelta()) + (Integer) val);
		}
		throw new Exception("Don't know how to mutate value of type '" + val.getClass().getName() + "'");
	}
	
	protected double getDelta()
	{
		return Math.abs(maxdelta - mindelta)*Math.random() + mindelta;		
	}
	
}
